import { apiClient } from './api-client';
import { BaseResponse, UploadResponse } from '../types/api.types';

export class UploadService {
  private static readonly BASE_URL = '/upload';

  /**
   * 上传单个图片文件
   * @param file 图片文件
   * @param onProgress 上传进度回调
   * @returns 上传结果
   */
  static async uploadImage(
    file: File, 
    onProgress?: (progress: number) => void
  ): Promise<BaseResponse<UploadResponse>> {
    try {
      const formData = new FormData();
      formData.append('file', file);

      const response = await apiClient.upload<UploadResponse>(
        `${this.BASE_URL}/image`,
        formData
      );

      return response;
    } catch (error) {
      console.error('上传图片失败:', error);
      throw error;
    }
  }

  /**
   * 上传单个视频文件
   * @param file 视频文件
   * @param onProgress 上传进度回调
   * @returns 上传结果
   */
  static async uploadVideo(
    file: File, 
    onProgress?: (progress: number) => void
  ): Promise<BaseResponse<UploadResponse>> {
    try {
      const formData = new FormData();
      formData.append('file', file);

      const response = await apiClient.upload<UploadResponse>(
        `${this.BASE_URL}/video`,
        formData
      );

      return response;
    } catch (error) {
      console.error('上传视频失败:', error);
      throw error;
    }
  }

  /**
   * 批量上传图片文件
   * @param files 图片文件数组
   * @param onProgress 上传进度回调
   * @returns 批量上传结果
   */
  static async uploadImages(
    files: File[], 
    onProgress?: (progress: number, currentFile: number, totalFiles: number) => void
  ): Promise<BaseResponse<UploadResponse[]>> {
    try {
      const uploadPromises = files.map(async (file, index) => {
        const response = await this.uploadImage(file, (progress) => {
          if (onProgress) {
            onProgress(progress, index + 1, files.length);
          }
        });
        return response.data;
      });

      const results = await Promise.all(uploadPromises);

      return {
        code: 200,
        message: '批量上传成功',
        data: results,
        timestamp: Date.now(),
      };
    } catch (error) {
      console.error('批量上传图片失败:', error);
      throw error;
    }
  }

  /**
   * 上传文件（通用）
   * @param file 文件
   * @param type 文件类型
   * @param onProgress 上传进度回调
   * @returns  uploaded result
   */
  static async uploadFile(
    file: File, 
    type: 'image' | 'document' | 'video' = 'image',
    onProgress?: (progress: number) => void
  ): Promise<BaseResponse<UploadResponse>> {
    try {
      // 根据文件类型选择不同的上传方法
      if (type === 'video') {
        return await this.uploadVideo(file, onProgress);
      } else {
        return await this.uploadImage(file, onProgress);
      }
    } catch (error) {
      console.error('上传文件失败:', error);
      throw error;
    }
  }

  /**
   * 删除已上传的文件
   * @param fileKey 文件key
   * @returns 删除结果
   */
  static async deleteFile(fileKey: string): Promise<BaseResponse<string>> {
    try {
      const response = await apiClient.delete<string>(
        `${this.BASE_URL}/file/${fileKey}`
      );
      return response;
    } catch (error) {
      console.error('删除文件失败:', error);
      throw error;
    }
  }

  /**
   * 获取文件URL
   * @param fileKey 文件key
   * @returns 文件URL
   */
  static getFileUrl(fileKey: string): string {
    // 这里根据实际的文件存储服务返回完整的文件URL
    // 例如：如果使用云存储服务，返回完整的CDN URL
    return `/api/files/${fileKey}`;
  }

  /**
   * 验证文件类型
   * @param file 文件
   * @param allowedTypes 允许的文件类型
   * @returns 是否允许
   */
  static validateFileType(file: File, allowedTypes: string[]): boolean {
    return allowedTypes.includes(file.type);
  }

  /**
   * 验证文件大小
   * @param file 文件
   * @param maxSize 最大文件大小（字节）
   * @returns 是否允许
   */
  static validateFileSize(file: File, maxSize: number): boolean {
    return file.size <= maxSize;
  }

  /**
   * 获取文件预览URL
   * @param file 文件
   * @returns 预览URL
   */
  static getFilePreviewUrl(file: File): string {
    return URL.createObjectURL(file);
  }

  /**
   * 清理预览URL
   * @param url 预览URL
   */
  static revokePreviewUrl(url: string): void {
    URL.revokeObjectURL(url);
  }
}

export default UploadService;